Imports System.Collections.Generic
Imports System.Text
Imports System.Reflection

Imports DbfDotNet.Core

Public Class SortOrder
	Friend mColumns As List(Of IndexColumn)
	Friend mTable As DbfTable
	Protected mUnique As Boolean

	Public Sub New(table As DbfTable, unique As Boolean)
		Me.New()
		mTable = table
		mUnique = unique
	End Sub

	Protected Sub New()
		mColumns = New List(Of IndexColumn)()
	End Sub

	Public Sub AddField(columnName As String)
		AddField(columnName, True)
	End Sub

	Public Sub AddField(columnName As String, ascending As Boolean)
		AddField(columnName, ascending, 0)
	End Sub

	Public Sub AddField(columnName As String, ascending As Boolean, width As Integer)
        Dim field As ColumnDefinition = mTable.mDbfFile.GetColumn(columnName)
		If field Is Nothing Then
			Throw New InvalidColumnException(columnName, "Unknown sort order column")
		End If
        mColumns.Add(New IndexColumn() With { _
            .ColumnName = columnName, _
            .Ascending = ascending, _
            .Width = width _
        })
	End Sub


	Friend ReadOnly Property Fields() As List(Of IndexColumn)
		Get
			Return mColumns
		End Get
	End Property


	Friend Function ToKeyString() As String
        Dim sb As StringBuilder = New StringBuilder()
		For i As Integer = 0 To mColumns.Count - 1
			If i > 0 Then
				sb.Append(" "C)
			End If
			sb.Append(mColumns(i).ColumnName)
		Next
		Return sb.ToString()
	End Function

	Friend ReadOnly Property IsUnique() As Boolean
		Get
			Return mUnique
		End Get
	End Property
End Class

Public Class SortOrder(Of TRecord As New)
	Inherits SortOrder
	Private Shared mRecordType As Type

	Shared Sub New()
		mRecordType = GetType(TRecord)
	End Sub

	Public Sub New(unique As Boolean, ParamArray columnNames As String())
		mUnique = unique
		For Each columnName As String In columnNames
			AddField(columnName)
		Next
	End Sub

	Public Shadows Sub AddField(columnName As String)
		AddField(columnName, True)
	End Sub

	Public Shadows Sub AddField(columnName As String, ascending As Boolean)
		AddField(columnName, ascending, 0)
	End Sub

	Public Shadows Sub AddField(columnName As String, ascending As Boolean, width As Integer)
        Dim field As Reflection.FieldInfo = mRecordType.GetField(columnName, BindingFlags.[Public] Or BindingFlags.NonPublic Or BindingFlags.IgnoreCase Or BindingFlags.Instance)
		If field Is Nothing Then
			Throw New InvalidColumnException(columnName, "Unknown sort order column")
		End If
        mColumns.Add(New IndexColumn() With { _
             .ColumnName = columnName, _
             .Ascending = ascending, _
            .Width = width _
        })
	End Sub

End Class
